home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NetNews Offline 2
/
NetNews Offline Volume 2.iso
/
news
/
comp
/
std
/
c
/
373
< prev
next >
Wrap
Internet Message Format
|
1996-08-06
|
5KB
Path: cs.tu-berlin.de!jutta
From: jutta@cs.tu-berlin.de (Jutta Degener)
Newsgroups: comp.std.c
Subject: Re: setjmp usage question
Date: 25 Feb 1996 12:24:24 GMT
Organization: Technical University of Berlin, Germany
Message-ID: <4gpkdo$jm8@news.cs.tu-berlin.de>
References: <4gnusq$7be@senator-bedfellow.MIT.EDU>
NNTP-Posting-Host: kugelbus.cs.tu-berlin.de
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
tada@athena.mit.edu (Michael J Zehr) writes:
> I'm trying to determine whether a particular usage of setjmp is
> sanctioned by the standard and I'm finding a compiler bug or whether my
> usage is non-conforming.
Your usage is non-conforming. The reason for that is not important
to what you're asking, but I'll mention it to get it out of the way.
The standard has restricted the ways in which setjmp() can be used:
# An invocation of the "setjmp" macro shall appear only in one of
# the following contexts:
#
# * The entire controlling expression of a selection of iteration
# statement;
#
# * one operand of a relational or equality operator with the
# other operand an integral constant expression, with the resulting
# expression being the entire controlling expression of a selection
# or iteration statement;
#
# * the operand of a unary ! operator with the resulting expression
# being the entire controlling expression of a selection or iteration
# statement; or
#
# * the entire expression of an expression statement (possibly cast
# to void).
# --- ANSI Section 4.6.1.1
Your statement,
> if (*error_code = setjmp(env[env_index++])) {
is neither of these cases (the '=' means assignment, not equality), so the
program's behavior is undefined.
Let's imagine you had written
if (setjmp(env[env_index++])) {
> Should this code work correctly? In particular, can a compiler
> increment env_index after longjmp is called?
I think the code might or might not work, and the compiler is free to
increment env_index after longjmp is called and flow control has returned
to the setjmp statement. The standard doesn't impose any ordering on
the act of "returning" from the longjmp invocation and on the side
effects from the setjmp() statement---macro invocations like setjmp()
do not imply sequence points in the way function invocations do.
> [Additional question because I'm curious: what happens to
> post-increments that are in parameters of the longjmp call?
I think that unless you take special care, the same applies, but you'll
find people to argue otherwise. (See below.)
For a bit of background---
The standard specifies one type of sequence point that's interesting
for us here:
# The order of evaluation of the function designator, the arguments,
# and subexpressions within the arguments is unspecified, but there is a
# sequence point before the actual call.
#
# --ANSI section 3.3.2.2, Function Calls.
That this is the only place that applies is in itself significant: there
are no special sequence points for longjmp and setjmp; they behave just
like any old function---or macro.
Setjmp, although it looks much like a function, is not described as a
function in the standard; it is a macro. Among other things, that means
you can't rely on a sequence point between the evaluation of setjmp's
argument and the "call".
Longjmp is described as a function in the standard. Does that mean it
is a function? Yes and no. There is a function called longjmp, and if
you write a call
#include <setjmp.h>
(longjmp)(env[env_index++], 1);
or
#include <setjmp.h>
#undef longjmp
longjmp(env[env_index++], 1);
or
#include <setjmp.h>
void (* f)(jmp_buf, int) = longjmp;
f(env[env_index++], 1);
so that longjmp can't possibly be a macro, you are guaranteed to get
a real function, complete with sequence point and all. In these cases,
(longjmp)(env[env_index++], 1);
is equivalent to
env_index++; longjmp(env[env_index - 1], 1);
since the side effects of the "++" operator must be complete before
the actual function is invoked.
But as long as you don't jump through any of the three hoops above
and naively use
#include <setjmp.h>
longjmp(env[env_index++], 1);
what you actually get may or may not be a call to the "real" longjmp
function, because
# Any function declared in a header may be additionally
# implemented as a macro
#
# -- ANSI Section 4.1.6, Use of Library Functions
Whether this means that
(a) users cannot rely on the sequence point between argument evaluation
and call unless they make sure they're using a "real" function
or whether this means that
(b) implementors who implement Standard C functions as macros must
guarantee that function-call like sequence points apply even in
the macro expansions
hasn't been formally decided within WG14 yet, as far as I remember.
Jutta Degener (jutta@cs.tu-berlin.de), speaking only for myself.